package com.unitd.base.frame.front;

import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.util.*;

/**
 * 自定义的给前端使用的菜单对象信息对象
 *
 * @author Hudan
 * @version 1.0
 * @filename TreeModel.java
 * @copyright www.unitd.com
 * @date 2019-01-25
 */
@Data
public class TreeModel {

    /** 菜单ID */
    private Integer id;
    /** 菜单名称 */
    private String name;
    /** 菜单值 */
    private String value;
    /** 菜单图标 */
    private String icon;
    /** 上级菜单ID */
    private Integer pid;
    /** 上级菜单名称 */
    private String pName;
    /** 是否叶子节点 */
    private boolean leaf;
    /** 是否展开 */
    private boolean spread;
    /** 附加信息 */
    private String extraAttr;
    /** 起始数据 */
    private Object originData;
    /** 子菜单列表 */
    private List<TreeModel> children;

    public TreeModel() {
    }

    public TreeModel(Integer id, String name, String value, String icon, Integer pid, boolean leaf) {
        this.id = id;
        this.name = name;
        this.value = value;
        this.icon = icon;
        this.pid = pid;
        this.leaf = leaf;
    }

    public void addChild(TreeModel child) {
        getChildren().add(child);
        child.setPName(name);
    }

    public List<TreeModel> getChildren() {
        return children == null ? (children = new ArrayList<>()) : children;
    }

    public void setChildren(List<TreeModel> children) {
        this.children = children;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }


    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }

        TreeModel other = (TreeModel) obj;
        if (id == null) {
            if (other.id != null) {
                return false;
            }
        } else if (!id.equals(other.id)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
    }


    public static TreeModel build(List<TreeModel> models) {
        TreeModel root = new TreeModel();

        //按pid排序
        Collections.sort(models, new Comparator<TreeModel>() {
            @Override
            public int compare(TreeModel o1, TreeModel o2) {
                return o1.getPid().compareTo(o2.getPid());
            }
        });

        Map<Integer, TreeModel> modelMap = new HashMap<>();
        for (TreeModel model : models) {
            if (!model.isLeaf()) {
                modelMap.put(model.getId(), model);
            }
        }
        for (TreeModel model : models) {
            if ((model.getPid() == 0 && !model.isLeaf()) || !modelMap.containsKey(model.getPid())) {
                root.addChild(model);
            } else {
                modelMap.get(model.getPid()).addChild(model);
            }
        }

        return root;
    }
}